package com.punai.standard.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.multi.ListValueMap;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfOutline;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.navigation.PdfDestination;
import com.itextpdf.kernel.pdf.navigation.PdfExplicitDestination;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.Style;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.VerticalAlignment;
import com.punai.common.core.domain.TreeBo;
import com.punai.common.properties.SqliteUpPathConfig;
import com.punai.common.utils.ParseContentUtil;
import com.punai.common.utils.SecurityUtils;
import com.punai.common.utils.StringUtils;
import com.punai.standard.domain.StaGxChapter;
import com.punai.standard.domain.StaGxFee;
import com.punai.standard.domain.vo.ExpenseCategoriesVo;
import com.punai.standard.domain.vo.StaSimplifyVo;
import com.punai.standard.mapper.StaGxChapterMapper;
import com.punai.standard.mapper.StaGxFeeMapper;
import com.punai.standard.mapper.StaLinkFeatureMapper;
import com.punai.standard.mapper.StaLinkGxfeeCategoryMapper;
import com.punai.standard.service.IStaGxFeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 工序分包费用项Service业务层处理
 *
 * @author zxw
 * @date 2022-12-13
 */
@Service
public class StaGxFeeServiceImpl extends ServiceImpl<StaGxFeeMapper,StaGxFee> implements IStaGxFeeService
{
    public static final int FONT_SIZE_20 = 20;
    public static final int FONT_SIZE_16 = 16;
    public static final int FONT_SIZE_12 = 12;
    @Autowired
    private StaGxFeeMapper gxFeeMapper;
    @Autowired
    private StaGxChapterMapper gxChapterMapper;
    @Autowired
    private StaLinkFeatureMapper linkFeatureMapper;
    @Autowired
    private StaLinkGxfeeCategoryMapper linkCategoryMapper;

    @Override
    public void createPdf(String versionId) {
        Long companyId = SecurityUtils.getCompanyId();

        try {
//            String pdfFileTemporaryPath = SqliteUpPathConfig.getTemplatezippath() + versionId + "temporary.pdf";
            String pdfFilePath = SqliteUpPathConfig.getTemplatezippath() + versionId + ".pdf";
            PdfWriter writer = new PdfWriter(pdfFilePath);
            PdfDocument pdfDoc = new PdfDocument(writer);
            Document document = new Document(pdfDoc, PageSize.A4);
            // 设置页面边距
            document.setMargins(36, 36, 36, 36);

            // 字体文件的路径，注意在此路径下放一个可以显示中文的字体，如宋体
//            String heiFontPath = "template/simhei.ttf";
            String kaiFontPath = "template/simkai.ttf";

            // 使用PdfFontFactory来创建字体
//            PdfFont heiFont = PdfFontFactory.createFont(heiFontPath, PdfEncodings.IDENTITY_H);
            PdfFont kaiFont = PdfFontFactory.createFont(kaiFontPath, PdfEncodings.IDENTITY_H);
            List<StaGxChapter> staGxChapters = gxChapterMapper.selectExport(versionId);

            // 章节
            List<TreeBo> result = TreeBo.convert(staGxChapters).get(0).getChildren();

            // 费用项
            List<StaGxFee> staGxFees = gxFeeMapper.selectExportPDF(versionId);

            // 根据章节分组
            ListValueMap<String, StaGxFee> gxFeeListMap = new ListValueMap<>();
            staGxFees.forEach(e -> gxFeeListMap.putValue(e.getChapterId(),e));

            // 特征
            List<StaSimplifyVo> itemIdFeatureNameList = linkFeatureMapper.selectFeatureBoGxAll(versionId, companyId);
            Map<String, String> featureStrMap = itemIdFeatureNameList.stream().collect(Collectors.toMap(StaSimplifyVo::getId, StaSimplifyVo::getName));

            // 关联类别
            List<Map<String, String>> maps = linkCategoryMapper.selectSimplifyMsgByVersionId(versionId);
            Map<String, String> idLinkMap = maps.stream().collect(Collectors.toMap(map -> map.get("id"), map -> map.get("categoryIds")));

            // 所有类别
            List<ExpenseCategoriesVo> expenseCategoriesVos = linkCategoryMapper.selectCjList(companyId);
            Map<String, ExpenseCategoriesVo> cjMap = expenseCategoriesVos.stream().collect(Collectors.toMap(ExpenseCategoriesVo::getId, Function.identity()));

            // 创建样式
            Style kaiBoldStyle = new Style().setFont(kaiFont).setBold().setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE);
            // 创建PDF文档的根目录
            PdfOutline rootOutline = pdfDoc.getOutlines(false);
            document.add(new Paragraph(""));

            List<Cell> cjCellList = new ArrayList<>();
            cjCellList.add(new Cell(1, 4).add(new Paragraph("材机类别").addStyle(kaiBoldStyle).setItalic()));
            cjCellList.add(new Cell().add(new Paragraph("名称").addStyle(kaiBoldStyle)));
            cjCellList.add(new Cell().add(new Paragraph("单位").addStyle(kaiBoldStyle)));
            cjCellList.add(new Cell().add(new Paragraph("规格型号").addStyle(kaiBoldStyle)));
            cjCellList.add(new Cell().add(new Paragraph("类型").addStyle(kaiBoldStyle)));
            printTree("", rootOutline, pdfDoc, document, kaiBoldStyle,kaiFont, result, gxFeeListMap, featureStrMap,cjCellList, idLinkMap, cjMap);

            document.close();
            log.debug("PDF成功创建");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void printTree(String prefix,PdfOutline chapterOutline,PdfDocument pdfDoc,Document document,Style kaiBoldStyle,PdfFont kaiFont,List<TreeBo> tree,ListValueMap<String, StaGxFee> gxFeeListMap,Map<String, String> featureStrMap,List<Cell> cjCellList,Map<String, String> idLinkMap,Map<String, ExpenseCategoriesVo> cjMap) throws IOException {
        if (tree == null) {
            return;
        }

        for (int i = 0; i < tree.size(); i++) {
            TreeBo chapter = tree.get(i);
            String titleText = prefix + (i + 1) + " " + chapter.getName();
            // 创建标题段落
            Paragraph title = new Paragraph(titleText).setTextAlignment(TextAlignment.CENTER).setFont(kaiFont).setFontSize(FONT_SIZE_20);

            // 创建对应内容的目录项
            PdfOutline contentOutline = chapterOutline.addOutline(titleText);
            PdfDestination contentDest = PdfExplicitDestination.createFit(pdfDoc.getPage(pdfDoc.getNumberOfPages()));
            contentOutline.addDestination(contentDest);

            // 将标题添加到文档
            document.add(title);

            List<StaGxFee> staGxFees = gxFeeListMap.get(chapter.getId());
            if (CollUtil.isNotEmpty(staGxFees)) {
                for (StaGxFee staGxFee : staGxFees) {
                    document.add(new Paragraph("")).add(new Paragraph("")).add(new Paragraph(""));
                    String gxId = staGxFee.getId();
                    String content = staGxFee.getContent();
                    staGxFee.setContent(ParseContentUtil.parseContent(content));

                    // 创建表格对象
                    Table table = new Table(new float[]{100, 200, 100, 200});
                    Cell cell11 = new Cell().add(new Paragraph("编码").addStyle(kaiBoldStyle));
                    Cell cell12 = new Cell().add(new Paragraph(String.valueOf(staGxFee.getCode())).setFont(kaiFont));
                    Cell cell13 = new Cell().add(new Paragraph("单位").addStyle(kaiBoldStyle));
                    Cell cell14 = new Cell().add(new Paragraph(staGxFee.getUnit()).setFont(kaiFont));
                    table.addCell(cell11);
                    table.addCell(cell12);
                    table.addCell(cell13);
                    table.addCell(cell14);
                    Cell cell21 = new Cell().add(new Paragraph("名称").addStyle(kaiBoldStyle));
                    Cell cell22 = new Cell(1, 3).add(new Paragraph(staGxFee.getName()).setFont(kaiFont));
                    table.addCell(cell21);
                    table.addCell(cell22);
                    Cell cell31 = new Cell().add(new Paragraph("计算规则").addStyle(kaiBoldStyle));
                    Cell cell32 = new Cell(1, 3).add(new Paragraph(staGxFee.getCalcRule()).setFont(kaiFont));
                    table.addCell(cell31);
                    table.addCell(cell32);
                    Cell cell41 = new Cell().add(new Paragraph("适用范围").addStyle(kaiBoldStyle));
                    Cell cell42 = new Cell(1, 3).add(new Paragraph(staGxFee.getSuitableRange()).setFont(kaiFont));
                    table.addCell(cell41);
                    table.addCell(cell42);
                    Cell cell51 = new Cell().add(new Paragraph("特征").addStyle(kaiBoldStyle));
                    Cell cell52 = new Cell(1, 3).add(new Paragraph(StringUtils.nvl(featureStrMap.get(staGxFee.getId()), " ")).setFont(kaiFont));
                    table.addCell(cell51);
                    table.addCell(cell52);
                    Cell cell61 = new Cell().add(new Paragraph("工作内容").addStyle(kaiBoldStyle));
                    Cell cell62 = new Cell(1, 3).add(new Paragraph(staGxFee.getContent()).setFont(kaiFont));
                    table.addCell(cell61);
                    table.addCell(cell62);
                    document.add(table);

                    if (idLinkMap.containsKey(gxId)) {
                        // 创建表格对象
                        Table cjTable = new Table(new float[]{200, 100, 500, 100});
                        // 添加表头
                        cjCellList.forEach(cjTable::addCell);

                        String[] categoryIdArray = idLinkMap.get(gxId).split(",");
                        for (String categoryId : categoryIdArray) {
                            ExpenseCategoriesVo categoriesVo = cjMap.get(categoryId);
                            cjTable.addCell(new Cell().add(new Paragraph(categoriesVo.getCategoriesName()).setFont(kaiFont).setTextAlignment(TextAlignment.CENTER)));
                            cjTable.addCell(new Cell().add(new Paragraph(categoriesVo.getUnit()).setFont(kaiFont).setTextAlignment(TextAlignment.CENTER)));
                            cjTable.addCell(new Cell().add(new Paragraph(categoriesVo.getSpec()).setFont(kaiFont).setTextAlignment(TextAlignment.CENTER)));
                            cjTable.addCell(new Cell().add(new Paragraph(categoriesVo.getType()).setFont(kaiFont).setTextAlignment(TextAlignment.CENTER)));
                        }
                        document.add(cjTable);
                    }
                }
            }
            document.flush();
            // 递归调用以处理子节点
            printTree(prefix + (i + 1) + ".",contentOutline, pdfDoc,document,kaiBoldStyle,kaiFont,chapter.getChildren(),gxFeeListMap,featureStrMap,cjCellList,idLinkMap,cjMap);
        }
    }
}